#ifndef _FNT_VIEWERPRIV_H_
#define _FNT_VIEWERPRIV_H_
#include "session.h"
#include "viewer.h"
#include "tracer.h"
#include "graph.priv.h"
#include <array>
#include <vector>
#include "viewershared.h"
struct ViewerPriv {
	Session* session;
	Viewer* viewer;

	ViewerShared* viewerShared;

	Graph graph;

	std::array<Cube, 9> cubes;
	std::array<std::pair<double, double>, 9> xfuncs;
	std::array<int, 9> cube_textures;
	std::array<QMatrix4x4, 9> cube_matrices;
	std::array<double, 9> min_voxel_sizes;
	double min_voxel_size;

	double max_dimension_size;

	QColor colors[COLOR_NUM];
	bool colorMode;
	bool checkedMode=true;

	QVector3D up, rgt;
	float radU;
	float rulerlength=0.0;
	Position curPos, tgtPos;
	QVector3D pickA, pickB;
	QMatrix4x4 mView, mrView, mProj, mrProj;

	int scale_factor;
	int fbo_width, fbo_height;

	QOpenGLFunctions_3_3_Core* funcs;
	std::vector<PathBuffer> pathBuffers;
	GLuint vao_fixed;
	GLuint vao_progr, vbo_progr;
	size_t num_progr;

	GLuint fbo_scale, fbotex_scale[2];
	GLuint fbo_opaque, fbotex_opaque[2];
	GLuint fbo_surface, fbotex_surface[2];
	GLuint fbo_edges, fbotex_edges[4];
	// fbo for surfaces
	GLuint fbo_cubes[3], fbotex_cubes[3 * 2];

	int pbiPath, pbiFixed;
	size_t num_path;

	MouseState mouse;
	int slice_num;
	int slice_shown;
	int slice_delta;
	bool slice_mode;
	bool show_edges;
	unsigned int textTexture;
	struct MeshVert {
		GLint x, y, z;
		GLfloat nx, ny, nz;
	};
	std::vector<MeshVert> meshVerts;
	std::vector<GLuint> meshIdxes;
	GLuint vao_mesh;
	GLuint vbo_mesh[2];

	std::vector<QColor> colormap;
	QTimer* timer;

	ViewerPriv(Session* s, Viewer* v);

	~ViewerPriv();
	void updateVoxelSizes(int i);
	bool setSession(Options* options, Graph gr, const std::array<Cube, 9>& _cubes, const std::array<std::pair<double, double>, 9>& _xfuncs, const std::array<double, 6>& bbox, double mvol);
	bool updateBoundingBox(const std::array<double, 6>& bbox);
	void setAxes(const Cube& c, PointGL* ptr);
	void updateXfunc(int ch, const std::pair<double, double>& xfunc);

	bool pickPoint(int x, int y);

	QVector3D toLocal(const Point& p) const;
	Point toGlobal(const QVector3D& p) const;
	void updateMVPMatrices();
	void updateCubeMatrix(int ch);

	void initializeGL();
	std::vector<PointGL> pathToPathGL(const std::vector<Point>& points, const Point &leftPoint , const Point &rightPoint);
	void initGraphPbi();
	int createPbi();
	void freePbi(int i);

	void zoomInOut(float d);
	void resizeFrameBuffers(int ww, int hh);
	void paintEdge();
	void paintOpaque();
	void paintSurface();
	void paintVolume();
	void paintRuler();
	void paintText(QImage* textImage,bool update=false);
	void paintBlank();
	void paintSorted(GLuint fbo);
	void paintFinish(GLuint fbo);

	void loadSurface(const QString& fn);
	void loadColormap(const QString& fn);
	void rotationTimeout();
	void toggleRotate();
};

#endif